#include <source_location>
#include <stdexcept>
#include <string>
#include <ranges>

#define throw_with_message_if_not(cond, msg)             \
    if (cond) [[likely]]                                 \
        static_cast<void>(0);                            \
    else                                                 \
        std::throw_with_nested(std::runtime_error(msg))  \
    

#define throw_if_not(cond) \
    throw_with_message_if_not(cond, "Condition failed: "#cond" in " + std::string(std::source_location::current().function_name()));


namespace utils
{
    template <class R, class V>
    concept view_of = std::ranges::input_range<R> && (std::same_as<std::ranges::range_value_t<R>, V> || std::convertible_to<std::ranges::range_value_t<R>, const V&>);
}
